﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Press.MVC.Data;
using System.Web.Security;

namespace Press.MVC.Services
{
    public class UserService : Press.MVC.Services.IUserService
    {

        IUserRepository _repository;
        public UserService()
        {

        }

        public UserService(IUserRepository repository)
        {
            _repository = repository;
        }

        //TODO SHOULD WE MOVE THIS TO THE USER service? along with the repository methods????
        /// <summary>
        /// Get Users that have admin access to a Blog
        /// </summary>
        /// <param name="categoryID"></param>
        /// <returns></returns>
        private IList<AspNetUser> GetUsersByBlog(int blogId)
        {

            return (from au in _repository.GetAspNetUsers()
                    join ub in _repository.GetBlogUserMap() on au.UserId equals ub.UserId
                    where ub.BlogId == blogId
                    select au).ToList();

        }

        public bool HasAdminAccessToBlog(int blogId, string userName)
        {
            bool userHasAccess = false;

            foreach (AspNetUser ap in this.GetUsersByBlog(blogId))
            {
                if (ap.UserId.Equals(Membership.GetUser(userName).ProviderUserKey))
                {
                    userHasAccess = true;
                    break;
                }
            }

            return userHasAccess;           
        }



        /// <summary>
        /// Returns all users
        /// </summary>
        /// <returns></returns>
        public List<User> GetUsers()
        {
            return _repository.GetUsers().ToList();
        }
        ///// <summary>
        ///// Gets a user by userName
        ///// </summary>
        ///// <param name="userName"></param>
        ///// <returns></returns>
        public User GetUser(string userName)
        {
            User result = _repository.GetUsers()
                .WithUserName(userName)
                .SingleOrDefault();

            if (result == null)
            {
                //this user is a guest, so set Anonymous settings for them
                result = new User("Guest", "", userName, "anon@nothing.com");

            }
            return result;

        }

        ///// <summary>
        ///// Deletes a user from the system
        ///// </summary>
        //public bool DeleteUser(string userName)
        //{
        //    return _repository.DeleteUser(userName);
        //}

        ///// <summary>
        ///// Register - Adds a new user into the system
        ///// </summary>
        ///// <param name="newUser"></param>
        ///// <param name="password"></param>
        ///// <param name="confirmPassword"></param>
        ///// <param name="question"></param>
        ///// <param name="answer"></param>
        ///// <returns></returns>
        //public bool Register(User newUser, string password, string confirmPassword, string question, string answer)
        //{


        //    //null/empty checks
        //    if (String.IsNullOrEmpty(password) || string.IsNullOrEmpty(question)
        //        || string.IsNullOrEmpty(answer))
        //        throw new InvalidOperationException("Please provide all information needed");

        //    //password check
        //    if (!password.Equals(confirmPassword, StringComparison.InvariantCultureIgnoreCase))
        //        throw new InvalidOperationException("Passwords do not match");


        //    //see if the user is in the system already
        //    User userCheck = GetUser(newUser.UserName);

        //    if (userCheck != null)
        //        throw new InvalidOperationException("This user already exists");

        //    //see if the email is in the system
        //    userCheck = _repository.GetUsers().WithEmail(newUser.Email).SingleOrDefault();

        //    if (userCheck != null)
        //        throw new InvalidOperationException("This email is already in our system");


        //    _repository.RegisterUser(newUser.FirstName, newUser.LastName, newUser.Email,
        //        newUser.UserName, password, question, answer);

        //    return true;

        //}

        //public bool CreateUser(string userName, string password, string email)
        //{
        //    bool result = false;
        //    MembershipCreateStatus status;

        //    Membership.CreateUser(userName, password, email, "mvcpress", "mvcpress", true, out status);

        //    if (status == MembershipCreateStatus.Success)
        //    {
        //        result = true;

        //    }
        //    else
        //    {
        //        if (status == MembershipCreateStatus.DuplicateEmail)
        //        {
        //            throw new InvalidOperationException("This email is already in our system");
        //        }
        //        if (status == MembershipCreateStatus.DuplicateUserName)
        //        {
        //            throw new InvalidOperationException("Need to use another login - this one's taken");
        //        }
        //        if (status == MembershipCreateStatus.InvalidEmail)
        //        {
        //            throw new InvalidOperationException("Invalid email address");
        //        }
        //        if (status == MembershipCreateStatus.InvalidPassword)
        //        {
        //            throw new InvalidOperationException("Invalid password. Needs to be stronger");
        //        }
        //        if (status == MembershipCreateStatus.UserRejected)
        //        {
        //            throw new InvalidOperationException("Cannot register at this time");
        //        }
        //    }

        //    return result;

        //}


        private bool AddUserToRoleMtaAdminRole(string userName)
        {
            Roles.AddUserToRole(userName, "MtaAdmin");
            return true;
        }

        public bool CreateMtaAdminUser(string userName, string password, string confirmPassword, string email, string reminderQuestion, string reminderAnswer)
        {
            RegisterUser(userName, password, confirmPassword, email, reminderQuestion, reminderAnswer);
            AddUserToRoleMtaAdminRole(userName);
            // TODO add the user to BlogUserAdmin many to many table
            return true;
        }

        public object RegisterUser(string userName, string password, string confirmPassword, string email, string reminderQuestion, string reminderAnswer)
        {
            bool result = false;
            MembershipCreateStatus status;

            if (!password.Equals(confirmPassword, StringComparison.InvariantCultureIgnoreCase))
                throw new InvalidOperationException("Passwords do not match");

            Membership.CreateUser(userName, password, email, reminderQuestion, reminderAnswer, true, out status);

            if (status == MembershipCreateStatus.Success)
            {
                result = true;

            }
            else
            {
                if (status == MembershipCreateStatus.DuplicateEmail)
                {
                    throw new InvalidOperationException("This email is already in our system");
                }
                if (status == MembershipCreateStatus.DuplicateUserName)
                {
                    throw new InvalidOperationException("Need to use another login - this one's taken");
                }
                if (status == MembershipCreateStatus.InvalidEmail)
                {
                    throw new InvalidOperationException("Invalid email address");
                }
                if (status == MembershipCreateStatus.InvalidPassword)
                {
                    throw new InvalidOperationException("Invalid password. Needs to be stronger");
                }
                if (status == MembershipCreateStatus.UserRejected)
                {
                    throw new InvalidOperationException("Cannot register at this time");
                }
            }

            return result;
        }


    }
}
